package com.panda.expand;

import com.panda.pojo.Context;
import com.panda.pojo.Element;
import lombok.Getter;
import lombok.Setter;

import java.util.Map;

@Setter
@Getter
public class ParamElementHandler implements ParamParser {

    //参数正则
    private String regex;

    //key
    private String key;

    //如果参数正则指定,该字段没有意义
    private String value;

    //能够识别的前缀
    private String prefix;

    //该键是否会是元素重复
    private boolean repetitive = false;

    //当出现多个相同的key时应该如何处理,有三种模式,分别是啊append[追加,默认],reject[拒绝],cover[覆盖]
    private String multi = "append";

    //当multi为append时用来分割多个值
    private String split = " ";

    @Override
    public String parseParam(Context context, Element element, String s) {

        Map<String, String> attributes = element.getAttributes();

        boolean containsKey = attributes.containsKey(key);

        //如果没有正则就不消费
        if (regex == null) {

            //如果如果没有给定值
            if (value == null) {

                if (containsKey) {

                    //null不追加
                    if (multi.equals("cover")) {
                        attributes.put(key, null);
                    } else if (multi.equals("reject")) {
                        throw new RuntimeException(prefix + " 不接受相同的key存在,拒绝的key: " + key + " 拒绝的值:" + attributes.get(key));
                    }


                } else {

                    //在未包含的清空下
                    attributes.put(key, null);
                }

            } else {

                onMulti(attributes, containsKey, value);

            }

            //不消费
            return s;

        }

        if (s == null) {
            throw new RuntimeException("处理 " + prefix + " 需要指令参数,但没有提供");
        }

        //如果匹配
        if (s.matches(regex)) {
            onMulti(attributes, containsKey, s);
            return null;
        } else {
            throw new RuntimeException(prefix + " 无法处理指令参数:" + s);
        }

    }

    private void onMulti(Map<String, String> attributes, boolean containsKey, String value) {

        if (containsKey) {

            switch (multi) {
                case "append":
                    attributes.put(key, attributes.get(key) + split + value);
                    break;
                case "cover":
                    attributes.put(key, value);
                    break;
                case "reject":
                    throw new RuntimeException(prefix + " 不接受相同的key存在,拒绝的key: " + key + " 拒绝的值:" + attributes.get(key));
            }

        } else {
            attributes.put(key, value);
        }
    }


}
